using System;
using System.Collections.Generic;
using System.Windows.Controls;
using Phoenix.Framework;
using Phoenix.Lifetime;

namespace Phoenix.Frames
{
    public class NavigationRequest
    {
        readonly WeakReference viewWeak;
        readonly Control view;

        public NavigationRequest(
            ControllerAction controllerAction,
            IEnumerable<ControllerActionParameter> parameters,
            Control view,
            IRequestTransientStore requestTransientStore,
            InvokeOptions options)
        {
            ControllerAction = controllerAction;
            Parameters = parameters;
            RequestTransientStore = requestTransientStore;
            Options = options;
            if (UseWeakReference)
                viewWeak = new WeakReference(view);
            else
                this.view = view;
        }

        public Control View
        {
            get
            {
                if (UseWeakReference)
                    return viewWeak.Target as Control;

                return view;
            }
        }

        private bool UseWeakReference
        {
            get { return (Options & InvokeOptions.UseWeakReference) == InvokeOptions.UseWeakReference; }
        }

        public InvokeOptions Options { get; private set; }
        public ControllerAction ControllerAction { get; set; }
        public IRequestTransientStore RequestTransientStore { get; private set; }
        public IEnumerable<ControllerActionParameter> Parameters { get; private set; }

        internal void Deactivate()
        {
            ViewModelEx(vm=>vm.Deactivated(this,EventArgs.Empty));
            if (View != null)
            {
                View.Focus();
                var viewModel = View.DataContext as ViewModelBase;
                if (viewModel != null)
                    viewModel.Deactivated(this, EventArgs.Empty);
            }
        }

        internal void Closing(RequestClosingEventArgs eventArgs)
        {
            ViewModelEx(vm => vm.Closing(this, eventArgs));
        }

        internal void Activate()
        {
            ViewModelEx(vm => vm.Activated(this, EventArgs.Empty));
        }

        private void ViewModelEx(Action<ViewModelBase> action)
        {
            if (View != null)
            {
                View.Focus();
                var viewModel = View.DataContext as ViewModelBase;
                if (viewModel != null)
                    action(viewModel);
            }
        }
    }
}